#!/bin/bash

# 颜色定义
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m' # 无颜色

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查是否为root用户
if [ "$(id -u)" != "0" ]; then
   log_error "此脚本必须以root权限运行" 
   exit 1
fi

# 应用配置
APP_DIR="/var/www/box-user"
APP_PORT=8000
GUNICORN_CONFIG="${APP_DIR}/gunicorn_config.py"
NGINX_CONFIG="/etc/nginx/conf.d/box-user.conf"

log_info "开始检查和修复网络访问问题..."

# 检查Gunicorn配置
log_info "检查Gunicorn绑定配置..."
if [ -f "$GUNICORN_CONFIG" ]; then
    BIND_SETTING=$(grep "bind" "$GUNICORN_CONFIG")
    log_info "当前绑定设置: $BIND_SETTING"
    
    # 检查是否绑定到127.0.0.1
    if grep -q "bind.*127.0.0.1" "$GUNICORN_CONFIG"; then
        log_info "更新Gunicorn绑定到所有接口 (0.0.0.0)..."
        sed -i 's/bind = "127.0.0.1:'"$APP_PORT"'"/bind = "0.0.0.0:'"$APP_PORT"'"/g' "$GUNICORN_CONFIG"
        log_info "已更新Gunicorn配置，现在绑定到0.0.0.0:$APP_PORT"
        GUNICORN_UPDATED=true
    else
        log_info "Gunicorn配置正确，绑定到所有接口或使用其他配置"
    fi
else
    log_warn "未找到Gunicorn配置文件: $GUNICORN_CONFIG"
fi

# 检查Django ALLOWED_HOSTS设置
log_info "检查Django ALLOWED_HOSTS配置..."
ENV_FILE="${APP_DIR}/.env"
SETTINGS_FILE="${APP_DIR}/boxuser/settings.py"
SETTINGS_PROD_FILE="${APP_DIR}/boxuser/settings_production.py"

update_allowed_hosts() {
    local file=$1
    if [ -f "$file" ]; then
        if grep -q "ALLOWED_HOSTS" "$file"; then
            log_info "更新 $file 中的ALLOWED_HOSTS..."
            # 备份文件
            cp "$file" "${file}.bak"
            
            # 确保ALLOWED_HOSTS包含必要的值
            if grep -q "ALLOWED_HOSTS.*=.*\[\]" "$file"; then
                # 空列表情况
                sed -i "s/ALLOWED_HOSTS.*=.*\[\]/ALLOWED_HOSTS = ['*', 'localhost', '127.0.0.1']/g" "$file"
            elif grep -q "ALLOWED_HOSTS.*=.*\[" "$file"; then
                # 列表情况但不完整
                if ! grep -q "ALLOWED_HOSTS.*'*'" "$file"; then
                    sed -i "s/ALLOWED_HOSTS.*=.*\[/ALLOWED_HOSTS = \['*', /g" "$file"
                fi
            elif grep -q "ALLOWED_HOSTS.*=.*env" "$file"; then
                # 使用环境变量
                log_info "使用环境变量设置ALLOWED_HOSTS，确保.env文件包含正确的值"
            fi
        fi
    fi
}

# 更新.env文件中的ALLOWED_HOSTS
if [ -f "$ENV_FILE" ]; then
    if grep -q "ALLOWED_HOSTS" "$ENV_FILE"; then
        # 检查并确保ALLOWED_HOSTS包含所有需要的值
        if ! grep -q "ALLOWED_HOSTS=.*\*" "$ENV_FILE" || ! grep -q "ALLOWED_HOSTS=.*localhost" "$ENV_FILE" || ! grep -q "ALLOWED_HOSTS=.*127.0.0.1" "$ENV_FILE"; then
            log_info "更新.env文件中的ALLOWED_HOSTS..."
            # 创建备份
            cp "$ENV_FILE" "${ENV_FILE}.bak"
            
            # 更新ALLOWED_HOSTS
            if grep -q "ALLOWED_HOSTS=" "$ENV_FILE"; then
                sed -i 's/ALLOWED_HOSTS=.*/ALLOWED_HOSTS=*,localhost,127.0.0.1/g' "$ENV_FILE"
            else
                echo "ALLOWED_HOSTS=*,localhost,127.0.0.1" >> "$ENV_FILE"
            fi
            log_info "已更新.env文件中的ALLOWED_HOSTS"
        else
            log_info ".env文件中的ALLOWED_HOSTS配置正确"
        fi
    else
        log_info "在.env文件中添加ALLOWED_HOSTS配置..."
        echo "ALLOWED_HOSTS=*,localhost,127.0.0.1" >> "$ENV_FILE"
    fi
else
    log_warn "未找到.env文件: $ENV_FILE"
fi

# 更新settings.py和settings_production.py文件
update_allowed_hosts "$SETTINGS_FILE"
update_allowed_hosts "$SETTINGS_PROD_FILE"

# 检查Nginx配置
log_info "检查Nginx配置..."
if [ -f "$NGINX_CONFIG" ]; then
    # 检查代理设置
    if grep -q "proxy_pass http://127.0.0.1:$APP_PORT" "$NGINX_CONFIG"; then
        log_info "更新Nginx代理配置，使用localhost而不是127.0.0.1..."
        # 创建备份
        cp "$NGINX_CONFIG" "${NGINX_CONFIG}.bak"
        # 更新配置
        sed -i 's|proxy_pass http://127.0.0.1:'"$APP_PORT"'|proxy_pass http://localhost:'"$APP_PORT"'|g' "$NGINX_CONFIG"
        # 重新加载Nginx配置
        systemctl reload nginx
        log_info "Nginx配置已更新"
        NGINX_UPDATED=true
    else
        log_info "Nginx代理配置正确"
    fi
else
    log_warn "未找到Nginx配置文件: $NGINX_CONFIG"
fi

# 检查防火墙设置
log_info "检查防火墙设置..."
if command -v firewall-cmd &> /dev/null; then
    FW_STATUS=$(firewall-cmd --state 2>/dev/null)
    if [ "$FW_STATUS" = "running" ]; then
        # 检查是否放行了端口
        if ! firewall-cmd --list-ports | grep -q "$APP_PORT/tcp"; then
            log_info "添加防火墙规则允许$APP_PORT端口访问..."
            firewall-cmd --permanent --add-port=$APP_PORT/tcp
            firewall-cmd --reload
            log_info "防火墙规则已更新"
        else
            log_info "防火墙已允许$APP_PORT端口访问"
        fi
    else
        log_info "防火墙未运行，跳过防火墙配置"
    fi
elif command -v ufw &> /dev/null; then
    UFW_STATUS=$(ufw status | grep "Status: active" 2>/dev/null)
    if [ ! -z "$UFW_STATUS" ]; then
        # 检查是否放行了端口
        if ! ufw status | grep -q "$APP_PORT/tcp"; then
            log_info "添加UFW防火墙规则允许$APP_PORT端口访问..."
            ufw allow $APP_PORT/tcp
            log_info "UFW防火墙规则已更新"
        else
            log_info "UFW防火墙已允许$APP_PORT端口访问"
        fi
    else
        log_info "UFW防火墙未运行，跳过防火墙配置"
    fi
else
    log_info "未检测到支持的防火墙工具，跳过防火墙配置"
fi

# 检查SELinux设置
if command -v getenforce &> /dev/null; then
    SELINUX_STATUS=$(getenforce)
    log_info "SELinux状态: $SELINUX_STATUS"
    
    if [ "$SELINUX_STATUS" = "Enforcing" ]; then
        log_info "配置SELinux允许网络连接..."
        if command -v setsebool &> /dev/null; then
            setsebool -P httpd_can_network_connect 1
            log_info "已允许HTTP服务连接网络"
        fi
        
        if command -v semanage &> /dev/null; then
            if ! semanage port -l | grep -q "http_port_t.*$APP_PORT"; then
                semanage port -a -t http_port_t -p tcp $APP_PORT
                log_info "已将$APP_PORT添加为HTTP端口"
            fi
        else
            log_warn "未找到semanage命令，无法完全配置SELinux"
        fi
    else
        log_info "SELinux未处于强制模式，跳过SELinux配置"
    fi
else
    log_info "未检测到SELinux，跳过SELinux配置"
fi

# 检查hosts文件，确保localhost和127.0.0.1映射正确
log_info "检查/etc/hosts文件..."
if ! grep -q "127.0.0.1.*localhost" /etc/hosts; then
    log_info "更新/etc/hosts文件..."
    cp /etc/hosts /etc/hosts.bak
    echo "127.0.0.1 localhost" >> /etc/hosts
    log_info "已更新hosts文件"
fi

# 重启应用服务
log_info "重启应用服务..."
if [ "$GUNICORN_UPDATED" = "true" ] || [ "$NGINX_UPDATED" = "true" ]; then
    supervisorctl restart box-user
    sleep 5
    log_info "应用服务已重启"
fi

# 测试网络连接
log_info "测试网络连接..."

# 测试本地端口绑定
log_info "检查端口绑定状态:"
netstat -tlnp | grep ":$APP_PORT " || ss -tlnp | grep ":$APP_PORT "

# 测试curl访问
log_info "测试HTTP访问:"
curl -s -o /dev/null -w "localhost:$APP_PORT HTTP状态码: %{http_code}\n" http://localhost:$APP_PORT/ || echo "访问localhost:$APP_PORT失败"
curl -s -o /dev/null -w "127.0.0.1:$APP_PORT HTTP状态码: %{http_code}\n" http://127.0.0.1:$APP_PORT/ || echo "访问127.0.0.1:$APP_PORT失败"

# 获取服务器IP并测试
SERVER_IP=$(hostname -I | awk '{print $1}')
if [ ! -z "$SERVER_IP" ]; then
    curl -s -o /dev/null -w "${SERVER_IP}:$APP_PORT HTTP状态码: %{http_code}\n" http://${SERVER_IP}:$APP_PORT/ || echo "访问${SERVER_IP}:$APP_PORT失败"
fi

log_info "网络访问问题修复完成！"
log_info "如果仍然无法访问应用，请检查应用日志和服务器状态。"
log_info "您可以使用以下命令查看日志:"
log_info "  supervisorctl status box-user"
log_info "  tail -f /var/log/box-user/supervisor.err.log"
log_info "  tail -f /var/log/box-user/gunicorn-error.log" 